// ValidationAspects
// Written by Mike Saunders
// Released under Microsoft Public License (Ms-PL)
using System.Collections.Generic;
using System.Linq;
using ValidationAspects.Sdk;

namespace ValidationAspects.Exceptions
{
	public class ValidationContextException : ValidationException
	{
		private readonly IEnumerable<ValidationException> _exceptions;

		public ValidationContextException(IEnumerable<ValidationException> exceptions)
		{
			Enforce.IsNotNull(exceptions, "exceptions");
			_exceptions = exceptions;
		}

		public override string Message
		{
			get
			{
				ValidationException exception = _exceptions.FirstOrDefault();
				return exception != null ? exception.Message : base.Message;
			}
		}

		public override IEnumerable<string> Messages
		{
			get { return Flatten().Select(e => e.Message); }
		}

		public override void SetContext(IValidationContext context)
		{
			base.SetContext(context);

			foreach (ValidationException exception in Exceptions.Where(e => e.GetType() != typeof(ValidationContextException) && e.Context == null))
			{
				exception.SetContext(context);
			}
		}

		public IEnumerable<ValidationException> Exceptions
		{
			get { return _exceptions; }
		}

		public IEnumerable<ValidationException> Flatten()
		{
			foreach (ValidationException validationException in Exceptions)
			{
				ValidationContextException contextException = validationException as ValidationContextException;
				if (contextException == null)
					yield return validationException;
				else
				{
					foreach (ValidationException exception in contextException.Flatten())
					{
						yield return exception;
					}
				}
			}
		}
	}
}